package com.aptana.css.core.parsing;

import com.aptana.parsing.ast.IParseNode;
import com.aptana.parsing.ast.IParseRootNode;
import com.aptana.parsing.WorkingParseResult;
import com.aptana.parsing.ast.ParseError;
import java.util.ArrayList;
import com.aptana.css.core.ICSSConstants;
import java.util.List;
import com.aptana.parsing.IParser;
import com.aptana.parsing.ParseResult;
import com.aptana.css.core.parsing.ast.*;
import com.aptana.parsing.IParseState;
import beaver.*;
import com.aptana.parsing.util.ParseUtil;
import com.aptana.parsing.ast.IParseError;
import com.aptana.parsing.ast.ParseRootNode;

/**
 * This class is a LALR parser generated by
 * <a href="http://beaver.sourceforge.net">Beaver</a> v0.9.6.1
 * from the grammar specification "CSS.grammar".
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
public class CSSParser extends Parser implements IParser {

	static final ParsingTables PARSING_TABLES = new ParsingTables(
		"U9pDM7jyJdKO$vxNXjbIKMoLQg5OgzSkREFLsjPCmapt#qqQOTIYt5A4GXRTTACB4Y9HIBe" +
		"eXPGIkNHFD#cg#yNJz$Sxp$lkU7V6zkaVv$ryp$FydkVxFB$dTpc$dJCWC0uByJIUnpDu5i" +
		"zXAHPZ2LPWEPPX4LRYHRo4b$4ALk5Ll8PtyGAQuIsinXjOWxLOXzVn9jRZRMp21ho3OXHX8" +
		"zx3PhnVowm7xoFhvJWaalKXL209PJW2Ts8QjPdKhaOy6k4fn20MTL4FzH671aZ0GRQUBWXW" +
		"YurhphYZJ9pqPbp8nitnZSjXN0ME8Vymsqys#gCzcg83sY0DwSX09jgY7R8m7GMOX0Mu0rD" +
		"m8wx53JPsCav39#IZa5coSI9Z1$h4dihO4xJ6LkXX8rkY91ARZJCPsS8dSX8ZAtjy1CUnHv" +
		"Cd76b6svtLtnGrIwDGnsUqXjsQx7BB7a9skMKFyMFB7lQUwEczs8xtUXcBnYBqTQpgGp8Qu" +
		"aYSZqlG2uTYh7hFmCDuCihNLUTZdFLDmZcUR4UppiciSohh741VJu$lMDn6tuIeRDUfzooV" +
		"diniktqPtzcSxVCusnVupFOf7kwbTgMoSI6vn$jmAvcNAVFY$JAlK6QVQfXcVGxVQtskvFh" +
		"CuWmqySp0u#Yjky3mxoR$Nik$Yln7oN#C$7uU$Y2s9xCTdgEEKUt1sWxpGpYTxQ2L8ShEU0" +
		"8dOoZbS4fZ7K7hI0oJCRYPrXHQpRXoSGj6SrnZS2jP8HbDLX3TS3zAaSVVoJOwXF7M$e0TG" +
		"HvEilO7aSgVoM9GmMUZZ32hxrhFnUsuY9Q9EfFklI#kYOp2i5nh2KTijFdSZyOw3xCnWtKP" +
		"srsu1$V1N7FXyBo8tlVnzZbfo5Fg4EwSHcZCS#5mpdvJFWb9VBQEvBdIZFlp6Ex3P3wDpVd" +
		"KjhIPMl79Ik49KBkiSVlCcX39QdPA77TAlDqfSTn3yTn37RWM7RbhStd2vF4yAE2vKCYJmQ" +
		"sX2vyx4rUVSJrit9cC2zguz6hZqXYNmRcgxCVngRqdQtUOltAa9hP1f7PJRIjRhV#u4xJ68" +
		"2iqMdq#0#7OEEQCvpwf6kamqZktYUpHH8SZpMXRiNedQfRYV4Ths35a1oqxVJzp0sPrgemt" +
		"XkkNO7r9FhwzLpRi3N8ldb35vyv7glKv79jtd6dCba6VgTFiYge#$vuSdvvCFsvVnfV8kQd" +
		"FMKhqNQTAxkbsfLnkfk$AX9a9DMRkBwTPduIzrYV1ha$qBaZGNM3uQUHdH5Q$HFbTFVmqjX" +
		"jusabHxM2LTXksqwqCKcOHETIoUBBbM6jtMfBjhpcjHMejiizjfZtVp7cNJ5OwhUOaoR9$5" +
		"NAiFSdQZxCZ2DjRyrJjh3sQKML6$aQurX3N9aHB4vr9znxYN7YhTgsPTiG1wtDZJGMPrfR4" +
		"34s45ot0rb7sO7IQ4YsDNbFmoY4ALJ#ByOcQQxNQflh4fDYUuNHLxWLgNqFqKtsboaKgzv1" +
		"NGJbUOsRMfawDQU3H6n93DVUiMeot1UFoYUNKLqNbxw5o8D6NwAJjuIe745DKdwtvYgbFL$" +
		"qhwklL$oMnnTK3fiyLgb#ktEcqxLPk9j6diev0ETixgNmMLTyNzDNL#5tKOvLVZsXIpPmTJ" +
		"LyAvT#KdPL$XZytq9kyLCfIeWwXQndeN$ry1dY#1gwYecDrjdjyyIf7UcoSmq0legowd0So" +
		"U1rFBFiVyKb4RWtxEOV8r$O6Zs#gAvtIgd7EZiez4cZy$yVhVAsvwjKYvY2LkndNQD$SGB9" +
		"oHtXipTKMVjQwUN8FgQRFEOnBLNsFA$cb0AU5wYEehwtaOvDoFuZAymEnKVNDDHiljYa$VV" +
		"$SG47uxAEiqJxY5JvdPwXSwiaNdgkTKVta4brgalz00g#jhf1$vM$vI$wKF#Ht#Kr#bLzaj" +
		"$niFJ$P#uy4rqhcopmPB#CqwdlYEwkzGhmiS#G9svejitX$L1wMXsIet2Wto10PBDTBkLmd" +
		"ryeW6IXbbhU0U4eUaLlaPXabDyb8kLLco7JDFbCUbx7ocCoL9zNo4l6YrLOIBrXjXRq$R#$" +
		"BxVqvubdYGRbVxfNxv4wPpDOTn2IPA1CivtPxlytUhv6#qaTAvMhe9NSJKsM0z9T#KY7tHE" +
		"nt4LDaceoGuJ9CbgXrCR5Cdf47P2crHVAqsXVAFx9BTietyhLy9L$A5x93FfVFv5FvH3wMZ" +
		"#H3#K2sopRPAblaVTaic#GzsIZloZkoGTwMjsIzl2dhPAsiaJVaTLajhychiag#PUff$49n" +
		"2DZ$vNIXth66E8LlEhaMCNnlDuZbDq#0C5yf1pRoM7SUQyvZpNbyUyjdEv$j0ie2ojCeIpY" +
		"M4d8xKEz0ctchBQGiP4nFsdgotOdjTEhfbCMKnRI5B08AypPe4AE8jU#1HRGLqLzaTOVle2" +
		"xQqzwUCfk#RCfsbEsiDAXBn4PaM$hQqfvcORuYwwXqL8$b#xvZ4LHqLtJsGLSFScg930#w#" +
		"Q3DVxe8J1G=");

	private WorkingParseResult fWorking;

	// Collect the errors into a list of IParseErrors
	private class CSSEvents extends Events
	{
		public void scannerError(Scanner.Exception e)
		{
		}

		public void syntaxError(Symbol token)
		{
		    //System.out.println("Error at: "+token.value);
			if (token == null || fWorking == null)
			{
				return;
			}
			fWorking.addError(new ParseError(ICSSConstants.CONTENT_TYPE_CSS, token, IParseError.Severity.ERROR));
		}

		public void unexpectedTokenRemoved(Symbol token)
		{
		}

		public void missingTokenInserted(Symbol token)
		{
		}

		public void misspelledTokenReplaced(Symbol token)
		{
		}

		public void errorPhraseRemoved(Symbol error)
		{
		}
	}

    public synchronized ParseResult parse(IParseState parseState) throws java.lang.Exception
    {
        WorkingParseResult working = new WorkingParseResult();
        parse(parseState, working);
        return working.getImmutableResult();
    }


	protected synchronized void parse(IParseState parseState, WorkingParseResult working) throws java.lang.Exception
	{
		fWorking = working;
        try
        {
    		// grab source
    		String source = parseState.getSource();
    
    		// create scanner and send source to it
    		CSSFlexScanner scanner = new CSSFlexScanner();
    		scanner.setSource(source);
    
    		// parse
    		ParseRootNode result = (ParseRootNode) parse(scanner);
    
    		// attach comments to parse root node
    		List<Symbol> comments = scanner.getComments();
    		List<CSSCommentNode> commentNodes = new ArrayList<CSSCommentNode>(comments.size());
    
    		for (Symbol comment : comments)
    		{
    			// @formatter:off
    			CSSCommentNode commentNode = new CSSCommentNode(
    				source.substring(comment.getStart(), comment.getEnd() + 1),
    				comment.getStart(),
    				comment.getEnd()
    			);
    			// @formatter:on
    
    			commentNodes.add(commentNode);
    		}
    
    		result.setCommentNodes(commentNodes.toArray(new IParseNode[commentNodes.size()]));
    
    		// update node offsets
    		int start = parseState.getStartingOffset();
    		int length = source.length();
    
    		// align root with zero-based offset
    		result.setLocation(0, length - 1);
    
    		if (start != 0)
    		{
    			// shift all offsets to the correct position
    			ParseUtil.addOffset(result, start);
    		}
    
    		// store results in the parse state
    		fWorking.setParseResult(result);
        }
        finally
        {
    		fWorking = null;
		}

	}

	public CSSParser() {
		super(PARSING_TABLES);


		report = new CSSEvents();
	}

	protected Symbol invokeReduceAction(int rule_num, int offset) {
		switch(rule_num) {
			case 0: // Program = Statements.p
			{
					final Symbol _symbol_p = _symbols[offset + 1];
					final ArrayList _list_p = (ArrayList) _symbol_p.value;
					final CSSNode[] p = _list_p == null ? new CSSNode[0] : (CSSNode[]) _list_p.toArray(new CSSNode[_list_p.size()]);
					
			return new CSSParseRootNode(p);
			}
			case 1: // Program = 
			{
					
			return new CSSParseRootNode();
			}
			case 2: // Statements = Statements Statement
			{
					((ArrayList) _symbols[offset + 1].value).add(_symbols[offset + 2].value); return _symbols[offset + 1];
			}
			case 3: // Statements = Statement
			{
					ArrayList lst = new ArrayList(); lst.add(_symbols[offset + 1].value); return new Symbol(lst);
			}
			case 14: // CharSet = CHARSET STRING.s SEMICOLON
			{
					final Symbol _symbol_s = _symbols[offset + 2];
					final String s = (String) _symbol_s.value;
					
			return new CSSCharSetNode(s);
			}
			case 15: // Import = IMPORT ImportWord.s SEMICOLON
			{
					final Symbol _symbol_s = _symbols[offset + 2];
					final String s = (String) _symbol_s.value;
					
			return new CSSImportNode(s);
			}
			case 16: // Import = IMPORT ImportWord.s List.w SEMICOLON
			{
					final Symbol _symbol_s = _symbols[offset + 2];
					final String s = (String) _symbol_s.value;
					final Symbol _symbol_w = _symbols[offset + 3];
					final List<CSSTextNode> w = (List<CSSTextNode>) _symbol_w.value;
					
			return new CSSImportNode(s, w.toArray(new CSSTextNode[w.size()]));
			}
			case 17: // Media = MEDIA_KEYWORD MediaExprs.m LCURLY RCURLY
			{
					final Symbol _symbol_m = _symbols[offset + 2];
					final ArrayList _list_m = (ArrayList) _symbol_m.value;
					final beaver.Symbol[] m = _list_m == null ? new beaver.Symbol[0] : (beaver.Symbol[]) _list_m.toArray(new beaver.Symbol[_list_m.size()]);
					
			List<CSSTextNode> list = new ArrayList<CSSTextNode>();

			for (Symbol symbol : m)
			{
				CSSTextNode text = new CSSTextNode((String) symbol.value);

				text.setLocation(symbol.getStart(), symbol.getEnd());
				list.add(text);
			}

			return new CSSMediaNode(list.toArray(new CSSTextNode[list.size()]));
			}
			case 18: // Media = MEDIA_KEYWORD MediaExprs.m LCURLY Statements.s RCURLY
			{
					final Symbol _symbol_m = _symbols[offset + 2];
					final ArrayList _list_m = (ArrayList) _symbol_m.value;
					final beaver.Symbol[] m = _list_m == null ? new beaver.Symbol[0] : (beaver.Symbol[]) _list_m.toArray(new beaver.Symbol[_list_m.size()]);
					final Symbol _symbol_s = _symbols[offset + 4];
					final ArrayList _list_s = (ArrayList) _symbol_s.value;
					final CSSNode[] s = _list_s == null ? new CSSNode[0] : (CSSNode[]) _list_s.toArray(new CSSNode[_list_s.size()]);
					
			List<CSSTextNode> list = new ArrayList<CSSTextNode>();

			for (Symbol symbol : m)
			{
				CSSTextNode text = new CSSTextNode((String) symbol.value);

				text.setLocation(symbol.getStart(), symbol.getEnd());
				list.add(text);
			}

			return new CSSMediaNode(list.toArray(new CSSTextNode[list.size()]), s);
			}
			case 19: // MediaExprs = MediaExprs MediaExpr
			{
					((ArrayList) _symbols[offset + 1].value).add(_symbols[offset + 2]); return _symbols[offset + 1];
			}
			case 20: // MediaExprs = MediaExpr
			{
					ArrayList lst = new ArrayList(); lst.add(_symbols[offset + 1]); return new Symbol(lst);
			}
			case 61: // Page = PAGE LCURLY RCURLY
			{
					
			return new CSSPageNode();
			}
			case 62: // Page = PAGE LCURLY Declarations.d RCURLY
			{
					final Symbol _symbol_d = _symbols[offset + 3];
					final List<CSSDeclarationNode> d = (List<CSSDeclarationNode>) _symbol_d.value;
					
			return new CSSPageNode(d);
			}
			case 63: // Page = PAGE COLON IDENTIFIER.s LCURLY RCURLY
			{
					final Symbol _symbol_s = _symbols[offset + 3];
					final String s = (String) _symbol_s.value;
					
			CSSPageSelectorNode pageSelector = new CSSPageSelectorNode(s);
			CSSPageNode result = new CSSPageNode();

			pageSelector.setLocation(_symbol_s.getStart(), _symbol_s.getEnd());
			result.setSelector(pageSelector);

			return result;
			}
			case 64: // Page = PAGE COLON IDENTIFIER.s LCURLY Declarations.d RCURLY
			{
					final Symbol _symbol_s = _symbols[offset + 3];
					final String s = (String) _symbol_s.value;
					final Symbol _symbol_d = _symbols[offset + 5];
					final List<CSSDeclarationNode> d = (List<CSSDeclarationNode>) _symbol_d.value;
					
			CSSPageSelectorNode pageSelector = new CSSPageSelectorNode(s);
			CSSPageNode result = new CSSPageNode(d);

			pageSelector.setLocation(_symbol_s.getStart(), _symbol_s.getEnd());
			result.setSelector(pageSelector);

			return result;
			}
			case 65: // FontFace = FONTFACE LCURLY RCURLY
			{
					
			return new CSSFontFaceNode();
			}
			case 66: // FontFace = FONTFACE LCURLY Declarations.d RCURLY
			{
					final Symbol _symbol_d = _symbols[offset + 3];
					final List<CSSDeclarationNode> d = (List<CSSDeclarationNode>) _symbol_d.value;
					
			return new CSSFontFaceNode(d);
			}
			case 67: // Namespace = NAMESPACE ImportWord.w SEMICOLON
			{
					final Symbol _symbol_w = _symbols[offset + 2];
					final String w = (String) _symbol_w.value;
					
			return new CSSNamespaceNode(w);
			}
			case 68: // Namespace = NAMESPACE IDENTIFIER.i ImportWord.w SEMICOLON
			{
					final Symbol _symbol_i = _symbols[offset + 2];
					final String i = (String) _symbol_i.value;
					final Symbol _symbol_w = _symbols[offset + 3];
					final String w = (String) _symbol_w.value;
					
			return new CSSNamespaceNode(i, w);
			}
			case 69: // AtRule = AT_RULE.a STRING.s SEMICOLON
			{
					final Symbol _symbol_a = _symbols[offset + 1];
					final String a = (String) _symbol_a.value;
					final Symbol _symbol_s = _symbols[offset + 2];
					final String s = (String) _symbol_s.value;
					
			return new CSSAtRuleNode(a, s);
			}
			case 70: // Rules = Rules.rs Rule.r
			{
					final Symbol _symbol_rs = _symbols[offset + 1];
					final CSSList rs = (CSSList) _symbol_rs.value;
					final Symbol _symbol_r = _symbols[offset + 2];
					final CSSRuleNode r = (CSSRuleNode) _symbol_r.value;
					
			rs.addChild(r);
			
			return rs;
			}
			case 71: // Rules = Rule.r
			{
					final Symbol _symbol_r = _symbols[offset + 1];
					final CSSRuleNode r = (CSSRuleNode) _symbol_r.value;
					
			CSSList list = new CSSList();
			
			list.addChild(r);
			
			return list;
			}
			case 72: // Rule = Selectors.s LCURLY RCURLY
			{
					final Symbol _symbol_s = _symbols[offset + 1];
					final List<CSSSelectorNode> s = (List<CSSSelectorNode>) _symbol_s.value;
					
			CSSRuleNode result = new CSSRuleNode(s);

			for (CSSSelectorNode selector : s)
			{
				selector.setParent(result);
			}

			return result;
			}
			case 73: // Rule = Selectors.s LCURLY Declarations.d RCURLY
			{
					final Symbol _symbol_s = _symbols[offset + 1];
					final List<CSSSelectorNode> s = (List<CSSSelectorNode>) _symbol_s.value;
					final Symbol _symbol_d = _symbols[offset + 3];
					final List<CSSDeclarationNode> d = (List<CSSDeclarationNode>) _symbol_d.value;
					
			CSSRuleNode result = new CSSRuleNode(s, d);

			for (CSSSelectorNode selector : s)
			{
				selector.setParent(result);
			}

			CSSSelectorNode firstSelector = s.get(0);

			for (CSSDeclarationNode declaration : d)
			{
				declaration.setParent(firstSelector);
			}

			return result;
			}
			case 75: // MozDocument = MOZ_DOCUMENT FunctionList.fs LCURLY RCURLY
			{
					final Symbol _symbol_fs = _symbols[offset + 2];
					final CSSList fs = (CSSList) _symbol_fs.value;
					
			CSSMozDocument doc = new CSSMozDocument();
			
			doc.addChild(fs);
			doc.addChild(new CSSList());
			
			return doc;
			}
			case 76: // MozDocument = MOZ_DOCUMENT FunctionList.fs LCURLY Rules.rs RCURLY
			{
					final Symbol _symbol_fs = _symbols[offset + 2];
					final CSSList fs = (CSSList) _symbol_fs.value;
					final Symbol _symbol_rs = _symbols[offset + 4];
					final CSSList rs = (CSSList) _symbol_rs.value;
					
			CSSMozDocument doc = new CSSMozDocument();
			
			doc.addChild(fs);
			doc.addChild(rs);
			
			return doc;
			}
			case 77: // FunctionList = FunctionList.fs COMMA Function.f
			{
					final Symbol _symbol_fs = _symbols[offset + 1];
					final CSSList fs = (CSSList) _symbol_fs.value;
					final Symbol _symbol_f = _symbols[offset + 3];
					final CSSExpressionNode f = (CSSExpressionNode) _symbol_f.value;
					
			fs.addChild(f);
			
			return fs;
			}
			case 78: // FunctionList = Function.f
			{
					final Symbol _symbol_f = _symbols[offset + 1];
					final CSSExpressionNode f = (CSSExpressionNode) _symbol_f.value;
					
			CSSList list = new CSSList();
			
			list.addChild(f);
			
			return list;
			}
			case 79: // MsViewPort = MS_VIEWPORT LCURLY Declarations.d RCURLY
			{
					final Symbol _symbol_d = _symbols[offset + 3];
					final List<CSSDeclarationNode> d = (List<CSSDeclarationNode>) _symbol_d.value;
					
			CSSMsViewPort viewPort = new CSSMsViewPort(d);
			for (CSSDeclarationNode declaration : d)
			{
				declaration.setParent(viewPort);
			}			
			return viewPort;
			}
			case 80: // Function = Identifier.i LPAREN RPAREN
			{
					final Symbol _symbol_i = _symbols[offset + 1];
					final String i = (String) _symbol_i.value;
					
			return new CSSFunctionNode(i, null);
			}
			case 81: // Function = Identifier.i LPAREN Expression.e RPAREN
			{
					final Symbol _symbol_i = _symbols[offset + 1];
					final String i = (String) _symbol_i.value;
					final Symbol _symbol_e = _symbols[offset + 3];
					final CSSExpressionNode e = (CSSExpressionNode) _symbol_e.value;
					
			return new CSSFunctionNode(i, e);
			}
			case 82: // List = List COMMA IDENTIFIER.i
			{
					final Symbol _symbol_i = _symbols[offset + 3];
					final String i = (String) _symbol_i.value;
					
		List<CSSTextNode> list = (List<CSSTextNode>) _symbols[offset + 1].value;
		CSSTextNode text = new CSSTextNode(i);

		text.setLocation(_symbol_i.getStart(), _symbol_i.getEnd());
		list.add(text);

		return _symbols[offset + 1];
			}
			case 83: // List = IDENTIFIER.i
			{
					final Symbol _symbol_i = _symbols[offset + 1];
					final String i = (String) _symbol_i.value;
					
		List<CSSTextNode> list = new ArrayList<CSSTextNode>();
		CSSTextNode text = new CSSTextNode(i);

		text.setLocation(_symbol_i.getStart(), _symbol_i.getEnd());
		list.add(text);

		return new Symbol(list);
			}
			case 84: // Declarations = Declaration.d
			{
					final Symbol _symbol_d = _symbols[offset + 1];
					final CSSDeclarationNode d = (CSSDeclarationNode) _symbol_d.value;
					
			List<CSSDeclarationNode> list = new ArrayList<CSSDeclarationNode>();

			list.add(d);

			return new Symbol(list);
			}
			case 85: // Declarations = Declaration.d SEMICOLON.s
			{
					final Symbol _symbol_d = _symbols[offset + 1];
					final CSSDeclarationNode d = (CSSDeclarationNode) _symbol_d.value;
					final Symbol s = _symbols[offset + 2];
					
			List<CSSDeclarationNode> list = new ArrayList<CSSDeclarationNode>();

			d.setHasSemicolon(s);
			list.add(d);

			return new Symbol(list);
			}
			case 86: // Declarations = Declarations.ds Declaration.d
			{
					final Symbol _symbol_ds = _symbols[offset + 1];
					final List<CSSDeclarationNode> ds = (List<CSSDeclarationNode>) _symbol_ds.value;
					final Symbol _symbol_d = _symbols[offset + 2];
					final CSSDeclarationNode d = (CSSDeclarationNode) _symbol_d.value;
					
			ds.add(d);

			return _symbols[offset + 1];
			}
			case 87: // Declarations = Declarations.ds Declaration.d SEMICOLON.s
			{
					final Symbol _symbol_ds = _symbols[offset + 1];
					final List<CSSDeclarationNode> ds = (List<CSSDeclarationNode>) _symbol_ds.value;
					final Symbol _symbol_d = _symbols[offset + 2];
					final CSSDeclarationNode d = (CSSDeclarationNode) _symbol_d.value;
					final Symbol s = _symbols[offset + 3];
					
			d.setHasSemicolon(s);
			ds.add(d);

			return _symbols[offset + 1];
			}
			case 88: // Declaration = Identifier.i COLON Expression.e
			{
					final Symbol _symbol_i = _symbols[offset + 1];
					final String i = (String) _symbol_i.value;
					final Symbol _symbol_e = _symbols[offset + 3];
					final CSSExpressionNode e = (CSSExpressionNode) _symbol_e.value;
					
			return new CSSDeclarationNode(i, e);
			}
			case 89: // Declaration = Identifier.i COLON Expression.e IMPORTANT.s
			{
					final Symbol _symbol_i = _symbols[offset + 1];
					final String i = (String) _symbol_i.value;
					final Symbol _symbol_e = _symbols[offset + 3];
					final CSSExpressionNode e = (CSSExpressionNode) _symbol_e.value;
					final Symbol s = _symbols[offset + 4];
					
			return new CSSDeclarationNode(i, e, s);
			}
			case 90: // Declaration = STAR.a Identifier.i COLON Expression.e
			{
					final Symbol _symbol_a = _symbols[offset + 1];
					final String a = (String) _symbol_a.value;
					final Symbol _symbol_i = _symbols[offset + 2];
					final String i = (String) _symbol_i.value;
					final Symbol _symbol_e = _symbols[offset + 4];
					final CSSExpressionNode e = (CSSExpressionNode) _symbol_e.value;
					
			return new CSSDeclarationNode(a + i, e);
			}
			case 91: // Declaration = STAR.a Identifier.i COLON Expression.e IMPORTANT.s
			{
					final Symbol _symbol_a = _symbols[offset + 1];
					final String a = (String) _symbol_a.value;
					final Symbol _symbol_i = _symbols[offset + 2];
					final String i = (String) _symbol_i.value;
					final Symbol _symbol_e = _symbols[offset + 4];
					final CSSExpressionNode e = (CSSExpressionNode) _symbol_e.value;
					final Symbol s = _symbols[offset + 5];
					
			return new CSSDeclarationNode(a + i, e, s);
			}
			case 92: // Declaration = error
			{
					
			return new CSSErrorDeclarationNode();
			}
			case 93: // Expression = Expression.e Separator.s Term.t
			{
					final Symbol _symbol_e = _symbols[offset + 1];
					final CSSExpressionNode e = (CSSExpressionNode) _symbol_e.value;
					final Symbol _symbol_s = _symbols[offset + 2];
					final String s = (String) _symbol_s.value;
					final Symbol _symbol_t = _symbols[offset + 3];
					final CSSExpressionNode t = (CSSExpressionNode) _symbol_t.value;
					
			return new CSSTermListNode(e, t, s);
			}
			case 94: // Expression = Expression.e Term.t
			{
					final Symbol _symbol_e = _symbols[offset + 1];
					final CSSExpressionNode e = (CSSExpressionNode) _symbol_e.value;
					final Symbol _symbol_t = _symbols[offset + 2];
					final CSSExpressionNode t = (CSSExpressionNode) _symbol_t.value;
					
			return new CSSTermListNode(e, t);
			}
			case 96: // Expression = error
			{
					
			return new CSSErrorExpressionNode();
			}
			case 97: // Term = Primitive.p
			{
					final Symbol _symbol_p = _symbols[offset + 1];
					final String p = (String) _symbol_p.value;
					
			return new CSSTermNode(p);
			}
			case 99: // Selectors = Selectors.ss Combinator.c Selector.s
			{
					final Symbol _symbol_ss = _symbols[offset + 1];
					final List<CSSSelectorNode> ss = (List<CSSSelectorNode>) _symbol_ss.value;
					final Symbol _symbol_c = _symbols[offset + 2];
					final String c = (String) _symbol_c.value;
					final Symbol _symbol_s = _symbols[offset + 3];
					final CSSSelectorNode s = (CSSSelectorNode) _symbol_s.value;
					
			CSSSelectorNode lastSelector = ss.get(ss.size() - 1);
			lastSelector.setCombinator(c);

			ss.add(s);

			return _symbols[offset + 1];
			}
			case 100: // Selectors = Selector.s
			{
					final Symbol _symbol_s = _symbols[offset + 1];
					final CSSSelectorNode s = (CSSSelectorNode) _symbol_s.value;
					
			List<CSSSelectorNode> list = new ArrayList<CSSSelectorNode>();

			list.add(s);

			return new Symbol(list);
			}
			case 101: // Selector = Selector.s SimpleSelector.ss
			{
					final Symbol _symbol_s = _symbols[offset + 1];
					final CSSSelectorNode s = (CSSSelectorNode) _symbol_s.value;
					final Symbol _symbol_ss = _symbols[offset + 2];
					final CSSSimpleSelectorNode ss = (CSSSimpleSelectorNode) _symbol_ss.value;
					
			s.addChild(ss);

			return s;
			}
			case 102: // Selector = SimpleSelector.ss
			{
					final Symbol _symbol_ss = _symbols[offset + 1];
					final CSSSimpleSelectorNode ss = (CSSSimpleSelectorNode) _symbol_ss.value;
					
			CSSSelectorNode selector = new CSSSelectorNode();

			selector.addChild(ss);

			return selector;
			}
			case 103: // SimpleSelector = TypeOrUniversalSelector.t AttributeSelectors.a
			{
					final Symbol _symbol_t = _symbols[offset + 1];
					final String t = (String) _symbol_t.value;
					final Symbol _symbol_a = _symbols[offset + 2];
					final ArrayList _list_a = (ArrayList) _symbol_a.value;
					final CSSAttributeSelectorNode[] a = _list_a == null ? new CSSAttributeSelectorNode[0] : (CSSAttributeSelectorNode[]) _list_a.toArray(new CSSAttributeSelectorNode[_list_a.size()]);
					
			return new CSSSimpleSelectorNode(t, a);
			}
			case 104: // SimpleSelector = TypeOrUniversalSelector.t
			{
					final Symbol _symbol_t = _symbols[offset + 1];
					final String t = (String) _symbol_t.value;
					
			return new CSSSimpleSelectorNode(t);
			}
			case 105: // SimpleSelector = AttributeSelectors.a
			{
					final Symbol _symbol_a = _symbols[offset + 1];
					final ArrayList _list_a = (ArrayList) _symbol_a.value;
					final CSSAttributeSelectorNode[] a = _list_a == null ? new CSSAttributeSelectorNode[0] : (CSSAttributeSelectorNode[]) _list_a.toArray(new CSSAttributeSelectorNode[_list_a.size()]);
					
			return new CSSSimpleSelectorNode(a);
			}
			case 106: // SimpleSelector = TypeOrUniversalSelector.t COLON.c1 NOT.n LPAREN AttributeSelector.s RPAREN
			{
					final Symbol _symbol_t = _symbols[offset + 1];
					final String t = (String) _symbol_t.value;
					final Symbol _symbol_c1 = _symbols[offset + 2];
					final String c1 = (String) _symbol_c1.value;
					final Symbol _symbol_n = _symbols[offset + 3];
					final String n = (String) _symbol_n.value;
					final Symbol _symbol_s = _symbols[offset + 5];
					final CSSAttributeSelectorNode s = (CSSAttributeSelectorNode) _symbol_s.value;
					
            return new CSSSimpleSelectorNode(t + c1 + n + "(" + s + ")");
			}
			case 107: // SimpleSelector = COLON.c1 NOT.n LPAREN AttributeSelector.s RPAREN
			{
					final Symbol _symbol_c1 = _symbols[offset + 1];
					final String c1 = (String) _symbol_c1.value;
					final Symbol _symbol_n = _symbols[offset + 2];
					final String n = (String) _symbol_n.value;
					final Symbol _symbol_s = _symbols[offset + 4];
					final CSSAttributeSelectorNode s = (CSSAttributeSelectorNode) _symbol_s.value;
					
            return new CSSSimpleSelectorNode(c1 + n + "(" + s + ")");
			}
			case 108: // SimpleSelector = TypeOrUniversalSelector.t COLON.c1 NOT.n LPAREN TypeOrUniversalSelector.s RPAREN
			{
					final Symbol _symbol_t = _symbols[offset + 1];
					final String t = (String) _symbol_t.value;
					final Symbol _symbol_c1 = _symbols[offset + 2];
					final String c1 = (String) _symbol_c1.value;
					final Symbol _symbol_n = _symbols[offset + 3];
					final String n = (String) _symbol_n.value;
					final Symbol _symbol_s = _symbols[offset + 5];
					final String s = (String) _symbol_s.value;
					
            return new CSSSimpleSelectorNode(t + c1 + n + "(" + s + ")");
			}
			case 109: // SimpleSelector = COLON.c1 NOT.n LPAREN TypeOrUniversalSelector.s RPAREN
			{
					final Symbol _symbol_c1 = _symbols[offset + 1];
					final String c1 = (String) _symbol_c1.value;
					final Symbol _symbol_n = _symbols[offset + 2];
					final String n = (String) _symbol_n.value;
					final Symbol _symbol_s = _symbols[offset + 4];
					final String s = (String) _symbol_s.value;
					
            return new CSSSimpleSelectorNode(c1 + n + "(" + s + ")");
			}
			case 110: // AttributeSelectors = AttributeSelectors AttributeSelector
			{
					((ArrayList) _symbols[offset + 1].value).add(_symbols[offset + 2].value); return _symbols[offset + 1];
			}
			case 111: // AttributeSelectors = AttributeSelector
			{
					ArrayList lst = new ArrayList(); lst.add(_symbols[offset + 1].value); return new Symbol(lst);
			}
			case 112: // AttributeSelector = CLASS.c
			{
					final Symbol _symbol_c = _symbols[offset + 1];
					final String c = (String) _symbol_c.value;
					
			return new CSSAttributeSelectorNode(c);
			}
			case 113: // AttributeSelector = COLON.c Identifier.i
			{
					final Symbol _symbol_c = _symbols[offset + 1];
					final String c = (String) _symbol_c.value;
					final Symbol _symbol_i = _symbols[offset + 2];
					final String i = (String) _symbol_i.value;
					
			return new CSSAttributeSelectorNode(c + i);
			}
			case 114: // AttributeSelector = COLON.c1 COLON.c2 Identifier.i
			{
					final Symbol _symbol_c1 = _symbols[offset + 1];
					final String c1 = (String) _symbol_c1.value;
					final Symbol _symbol_c2 = _symbols[offset + 2];
					final String c2 = (String) _symbol_c2.value;
					final Symbol _symbol_i = _symbols[offset + 3];
					final String i = (String) _symbol_i.value;
					
			return new CSSAttributeSelectorNode(c1 + c2 + i);
			}
			case 115: // AttributeSelector = COLON Function.f
			{
					final Symbol _symbol_f = _symbols[offset + 2];
					final CSSExpressionNode f = (CSSExpressionNode) _symbol_f.value;
					
			return new CSSAttributeSelectorNode(f);
			}
			case 116: // AttributeSelector = HASH.h
			{
					final Symbol _symbol_h = _symbols[offset + 1];
					final String h = (String) _symbol_h.value;
					
			return new CSSAttributeSelectorNode(h);
			}
			case 117: // AttributeSelector = LBRACKET.l Identifier.i RBRACKET.r
			{
					final Symbol _symbol_l = _symbols[offset + 1];
					final String l = (String) _symbol_l.value;
					final Symbol _symbol_i = _symbols[offset + 2];
					final String i = (String) _symbol_i.value;
					final Symbol _symbol_r = _symbols[offset + 3];
					final String r = (String) _symbol_r.value;
					
			return new CSSAttributeSelectorNode(l + i + r);
			}
			case 118: // AttributeSelector = LBRACKET.l Identifier.i AttributeValueOperator.o IdentiferOrString.s RBRACKET.r
			{
					final Symbol _symbol_l = _symbols[offset + 1];
					final String l = (String) _symbol_l.value;
					final Symbol _symbol_i = _symbols[offset + 2];
					final String i = (String) _symbol_i.value;
					final Symbol _symbol_o = _symbols[offset + 3];
					final String o = (String) _symbol_o.value;
					final Symbol _symbol_s = _symbols[offset + 4];
					final String s = (String) _symbol_s.value;
					final Symbol _symbol_r = _symbols[offset + 5];
					final String r = (String) _symbol_r.value;
					
			return new CSSAttributeSelectorNode(l + i + " " + o + " " + s + r);
			}
			case 4: // Statement = CharSet
			case 5: // Statement = Import
			case 6: // Statement = Media
			case 7: // Statement = Page
			case 8: // Statement = FontFace
			case 9: // Statement = Namespace
			case 10: // Statement = AtRule
			case 11: // Statement = Rule
			case 12: // Statement = MozDocument
			case 13: // Statement = MsViewPort
			case 21: // MediaExpr = IDENTIFIER
			case 22: // MediaExpr = PROPERTY
			case 23: // MediaExpr = COLOR
			case 24: // MediaExpr = COLON
			case 25: // MediaExpr = RCURLY
			case 26: // MediaExpr = STRING
			case 27: // MediaExpr = LBRACKET
			case 28: // MediaExpr = CLASS
			case 29: // MediaExpr = HASH
			case 30: // MediaExpr = SEMICOLON
			case 31: // MediaExpr = URL
			case 32: // MediaExpr = STAR
			case 33: // MediaExpr = SELECTOR
			case 34: // MediaExpr = COMMA
			case 35: // MediaExpr = NUMBER
			case 36: // MediaExpr = PERCENTAGE
			case 37: // MediaExpr = LENGTH
			case 38: // MediaExpr = EMS
			case 39: // MediaExpr = EXS
			case 40: // MediaExpr = ANGLE
			case 41: // MediaExpr = TIME
			case 42: // MediaExpr = FREQUENCY
			case 43: // MediaExpr = PAGE
			case 44: // MediaExpr = AT_RULE
			case 45: // MediaExpr = CHARSET
			case 46: // MediaExpr = MEDIA_KEYWORD
			case 47: // MediaExpr = FONTFACE
			case 48: // MediaExpr = NAMESPACE
			case 49: // MediaExpr = IMPORT
			case 50: // MediaExpr = RBRACKET
			case 51: // MediaExpr = LPAREN
			case 52: // MediaExpr = PLUS
			case 53: // MediaExpr = SLASH
			case 54: // MediaExpr = MINUS
			case 55: // MediaExpr = RPAREN
			case 56: // MediaExpr = IMPORTANT
			case 57: // MediaExpr = GREATER
			case 58: // MediaExpr = EQUAL
			case 59: // MediaExpr = INCLUDES
			case 60: // MediaExpr = DASHMATCH
			case 74: // Rule = error
			case 95: // Expression = Term
			case 98: // Term = Function
			case 119: // ImportWord = STRING
			case 120: // ImportWord = URL
			case 121: // Identifier = IDENTIFIER
			case 122: // Identifier = PROPERTY
			case 123: // IdentiferOrString = IDENTIFIER
			case 124: // IdentiferOrString = STRING
			case 125: // Separator = SLASH
			case 126: // Separator = COMMA
			case 127: // Separator = PLUS
			case 128: // Separator = MINUS
			case 129: // Separator = EQUAL
			case 130: // Combinator = COMMA
			case 131: // Combinator = PLUS
			case 132: // Combinator = GREATER
			case 133: // Primitive = NUMBER
			case 134: // Primitive = PERCENTAGE
			case 135: // Primitive = LENGTH
			case 136: // Primitive = EMS
			case 137: // Primitive = EXS
			case 138: // Primitive = ANGLE
			case 139: // Primitive = TIME
			case 140: // Primitive = FREQUENCY
			case 141: // Primitive = STRING
			case 142: // Primitive = IDENTIFIER
			case 143: // Primitive = URL
			case 144: // Primitive = COLOR
			case 145: // TypeOrUniversalSelector = IDENTIFIER
			case 146: // TypeOrUniversalSelector = STAR
			case 147: // TypeOrUniversalSelector = SELECTOR
			case 148: // AttributeValueOperator = EQUAL
			case 149: // AttributeValueOperator = INCLUDES
			case 150: // AttributeValueOperator = DASHMATCH
			case 151: // AttributeValueOperator = BEGINS_WITH
			case 152: // AttributeValueOperator = ENDS_WITH
			{
				return _symbols[offset + 1];
			}
			default:
				throw new IllegalArgumentException("unknown production #" + rule_num);
		}
	}
}
